package httpx

import (
	"io"
	"time"
)

func ProgressRead(r io.Reader, total int64, progress ...ProgressFunc) io.Reader {
	return io.TeeReader(r, &pw{total: total, progress: progress})
}

type pw struct {
	cur      int64
	total    int64
	pct      int64
	progress []ProgressFunc
	lastRpt  time.Time
}

func (w *pw) report() {
	if len(w.progress) == 0 {
		return
	}
	canRpt := w.cur == w.total || time.Since(w.lastRpt) >= time.Second*3
	if !canRpt {
		return
	}

	if w.total == 0 {
		for _, fn := range w.progress {
			if fn != nil {
				go fn(w.cur, w.total, 0)
			}
		}
	} else if pct := w.cur * 100 / w.total; pct != w.pct {
		w.pct = pct
		for _, fn := range w.progress {
			go fn(w.cur, w.total, pct)
		}
	}
	w.lastRpt = time.Now()
}

func (w *pw) Write(p []byte) (n int, err error) {
	n = len(p)
	w.cur += int64(n)
	w.report()
	return
}
